local skynet = require "skynet"

local lib = {}

local function stringify(v)
	if type(v) == "string" then
		v = string.format("%q", v)
	end

	return tostring(v)
end

-- 删除table中的元素  
function lib.tableRemoveForKey(tbl,key)  
    --新建一个临时的table  
    local tmp ={}  
  
    --把每个key做一个下标，保存到临时的table中，转换成{1=a,2=c,3=b}   
    --组成一个有顺序的table，才能在while循环准备时使用#table  
    for i in pairs(tbl) do  
        table.insert(tmp,i)  
    end  
  
    local newTbl = {}  
    --使用while循环剔除不需要的元素  
    local i = 1  
    while i <= #tmp do  
		local val = tmp [i]  
        if val == key then  
            --如果是需要剔除则remove   
            -- table.remove(tmp,i)  
         else  
            --如果不是剔除，放入新的tabl中  
            newTbl[val] = tbl[val]  
         end  
		 i = i + 1  
	end 
	-- tbl =  newTbl
    return newTbl  
end

function lib.stringify_table(args)
	local result = {}

	if type(args) == "table" then
		for k, v in pairs(args) do
			k = stringify(k)
			v = stringify(v)

			result[k] = v
		end
	end

	return result
end

function lib.stringify_table_val(args)
	local result = {}

	if type(args) == "table" then
		for k, v in pairs(args) do
			v = stringify(v)

			result[k] = v
		end
	end

	return result
end

function lib.split_string(str)
	local arr = {}

	for i in string.gmatch(str, "%S+") do
		table.insert(arr, i)
	end

	return arr
end

--only support one dimension table
function lib.dump(args)
	local result = {}
	if type(args) == "table" then
		local indent = "    "
		result[#result + 1] = "{\n"

		for k, v in pairs(args) do
			k = stringify(k)

			if type(v) == "table" then
				v = lib.dump(v)
			else
				v = stringify(v)
			end

			-- result[#result + 1] = indent
			result[#result + 1] = k
			result[#result + 1] = " = "
			result[#result + 1] = v
			result[#result + 1] = "\n"
		end

		result[#result + 1] = "}"
	else
		args = stringify(args)
		result[#result + 1] = args
	end

	result = table.concat(result, "")

	return result
end

function lib.dumpprint(args)
	local result = lib.dump(args)
	skynet.error("dumpprint---- "..result)
end

function lib.print(...)
	skynet.error(...)
	-- print(...)
end

function lib.serialize(obj)  
    local lua = ""  
    local t = type(obj)  
    if t == "number" then  
        lua = lua .. obj  
    elseif t == "boolean" then  
        lua = lua .. tostring(obj)  
    elseif t == "string" then  
        lua = lua .. string.format("%q", obj)  
    elseif t == "table" then  
        lua = lua .. "{\n"  
		for k, v in pairs(obj) do  
			lua = lua .. lib.serialize(k) .. "=" .. lib.serialize(v) .. ",\n"  
		end  
		local metatable = getmetatable(obj)  
			if metatable ~= nil and type(metatable.__index) == "table" then  
			for k, v in pairs(metatable.__index) do  
				lua = lua .. lib.serialize(k) .. "=" .. lib.serialize(v) .. ",\n"  
			end  
		end  
        lua = lua .. "}"  
    elseif t == "nil" then  
        return nil  
    else  
        error("can not serialize a " .. t .. " type.")  
    end  
    return lua  
end  
  
-- function lib.unserialize(lua)  
--     local t = type(lua)  
--     if t == "nil" or lua == "" then  
--         return nil  
--     elseif t == "number" or t == "string" or t == "boolean" then  
--         lua = tostring(lua)  
--     else  
--         error("can not unserialize a " .. t .. " type.")  
--     end  
--     lua = "return " .. lua  
--     local func = loadstring(lua)  
--     if func == nil then  
--         return nil  
--     end  
--     return func()  
-- end  

function lib.stringsplit(str, delimiter)
	if str==nil or str=='' or delimiter==nil then
		return {}
	end
	
    local result = {}
    for match in (str..delimiter):gmatch("(.-)"..delimiter) do
        table.insert(result, match)
    end
    return result
end

function lib.tablecopy(obj)  
	local ret = {}
    for k, v in pairs(obj) do  
        ret[k] = v
    end  
	return ret
end  

function lib.tablerandom(obj,num)  
	local temps = {}
    for k, v in pairs(obj) do  
		if v then
        	temps[#temps + 1] = k
		end
	end  
	local ret = {}
	if #temps > 0 then
		for i = 1,num do
			local index = math.random(1,#temps)
			local k = temps[index]
			ret[#ret+1] = obj[k]
			temps[index] = temps[#temps]
			temps[#temps] = nil
			if #temps == 0 then
				break
			end
			-- print (obj[k].uid)
		end
	end
	return ret
end  


function lib.arraytostring(array)
	if array==nil then
		return ""
	end
	
    local result = ""
	if type(array) == "table" then
		for k, v in lib.pairsByKeys(array) do
			if v ~= nil then
				-- skynet.error("arraytostring "..k)
				if result == "" then
					result = tostring(v)
				else
					result = result .. "," .. tostring(v)
				end
			end
		end
	else
		result = tostring(array)
	end
    return result
end

function lib.tabletostring(obj)
	if obj==nil then
		return ""
	end
	
    local result = ""
	for k, v in pairs(obj) do
		if v ~= nil then
			-- print("vvvvvvvvvvvvvvvvvvvvvvv  ",v)
			if result == "" then
				result = lib.arraytostring(v)
			else
				result = result .. ";" .. lib.arraytostring(v)
			end
		end
	end
    return result
end


function lib.dbtabletoarray(dbtable)
    local a = {}  
    for n in pairs(dbtable) do  
        a[#a+1] = n  
    end  
    table.sort(a,function (aa,bb)
		return tonumber(aa) < tonumber(bb)
	end)

	local ret = {}
	for i in ipairs(a) do  
        ret[i] =  dbtable[a[i]] 
    end 
    return ret
end


function lib.getDataForString(str,id)
    id = tonumber(id)
    local data = utils.stringsplit(str,';')

    for k, v in pairs(data) do
        local value = utils.stringsplit(v,',')
        if tonumber(value[1]) == id then
            return value
        end
    end
    return nil
end


function lib.pairsByKeys(t)  
    local a = {}  
    for n in pairs(t) do  
        a[#a+1] = n  
		-- print("----- pairsByKeys -- "..n)
    end  
    table.sort(a)  
    local i = 0  
    return function()  
        i = i + 1  
        return a[i], t[a[i]]  
    end  
end 


function lib.sortKeys(t)  
    local a = {}  
    for n in pairs(t) do  
        a[#a+1] = n  
    end  
    table.sort(a)  
	for i in ipairs(a) do  
        t[a[i]] = i  
    end 
	return t
end 


function lib.tableSortToArray(t)  
    local a = {}  
    for n in pairs(t) do  
        a[#a+1] = n  
    end  
	table.sort(a,function ( aa,bb )
		return tonumber(aa) < tonumber(bb)
	end)  
	local ret = {}
	for i in ipairs(a) do  
        ret[#ret + 1] = t[a[i]]
    end 
	return ret
end 


function lib.url_encode(s)
    s = string.gsub(s, "([^_^%w%.%- ])", function(c) return string.format("%%%02X", string.byte(c)) end)  
    return string.gsub(s, " ", "+")
end

function lib.url_decode(s)
    s = string.gsub(s, '%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end)
    return s
end  


function lib.get_current_datetime()
	local datetime = os.date("%Y-%m-%d %H:%M:%S")

	return datetime
end

--获取一天后几点的时间
function lib.getHourTime(future_hour)
	local future_days = 1
	local cur_timestamp = os.time()
	local one_hour_timestamp = 24*60*60
	local temp_time = cur_timestamp + one_hour_timestamp * future_days
	local temp_date = os.date("*t", temp_time)
	return os.time(
		{year=temp_date.year, month=temp_date.month, day=temp_date.day, hour=future_hour})	
end

--获取当前时间到时间点的差
function lib.getDistanceTime(hour,min,sec)
	local now_date = os.date("*t",os.time())
	min = min or 0
	sec = sec or 0
	local diff = 0
	if hour == 24 then
		hour = 23
		min = 59
		sec = 59
		diff = 1
	end
	if hour * 60 + min < now_date.hour * 60 + now_date.min then
		now_date = os.date("*t",os.time() + 24 * 60 * 60)
	end
	-- 获取当前时间
	-- 当天的最后时间
	local today_time = os.time{
		year=now_date.year, 
		month=now_date.month, 
		day=now_date.day, 
		hour=hour,min=min,sec=sec
	}
	-- 当前时间与零点的时间差
	local time = (today_time - os.time()) + diff
	return time
end


function lib.time(milliscond)
	if milliscond then
		return skynet.time()
	end
	return math.ceil(skynet.time())
	-- return os.time()
end

function lib.millisecond()
	return math.ceil(skynet.time() * 1000)
end


function lib.loaddata (_dbname, start,num,readdb )
	-- print ("start "..start)
	-- num = 10
    local ret = skynet.call("mysqlserver", "lua", "getData", _dbname,"*","uid>"..start.." limit "..num)
    readdb(ret)
    -- utils.dumpprint(ret)
    if #ret > 0 then
        local lastid = ret[#ret].uid
        if lastid - start >= num then
            lib.loaddata(_dbname, lastid,num,readdb)
        end
    end
end

-- %c	日期和时间	(09/16/98 23:48:10)
-- %d	一个月中的第几天	(28)[0 - 31]
-- %H	24小时制中的小时数	(18)[00 - 23]
-- %I	12小时制中的小时数	(10)[01 - 12]
-- %j	一年中的第几天	(209)[01 - 366]
-- %M	分钟数	(48)[00 - 59]
-- %m	月份数	(09)[01 - 12]
-- %P	上午或下午	(pm)[am - pm]
-- %S	一分钟之内秒数	(10)[00 - 59]
-- %w	一星期中的第几天	(3)[0 - 6 = 星期天 - 星期六]
-- %W	一年中的第几个星期　　	(2)0 - 52
-- %x	日期	(09/16/98)
-- %X	时间	(23:48:10)
-- %y	两位数的年份	(16)[00 - 99]
-- %Y	完整的年份	(2016)


return lib